﻿using System;
using Ewk.Configuration;
using Ewk.Math.Algebra.Algorithms.Matrices;
using Ewk.Math.Algebra.Algorithms.Matrices.Adjugate;
using Ewk.Math.Algebra.Algorithms.Matrices.Determinant;
using Ewk.Math.Algebra.Algorithms.Matrices.Inverse;
using Ewk.Math.Algebra.Algorithms.Matrices.Rank;
using Ewk.Math.Numerics;

namespace Ewk.Math.Algebra.Factories
{
    /// <summary>
    /// Resolves registered and known types.
    /// </summary>
    public static class UnityContainerSetup
    {
        /// <summary>
        /// Initializes the <see cref="IDependencyResolver"/> with the default types.
        /// </summary>
        public static void Initialize()
        {
            var resolver = new UnityDependencyResolver();
            InitializeDefaultTypes(resolver);
            DependencyConfiguration.DependencyResolver = resolver;
        }

        #region Initialization

        private static void InitializeDefaultTypes(IDependencyResolver resolver)
        {
            InitializeForElementType<int>(resolver);
            InitializeForElementType<double>(resolver);
            InitializeForElementType<Complex>(resolver);
        }

        private static void InitializeForElementType<T>(IDependencyResolver resolver)
            where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
        {
            resolver.EnsureIsRegistered<IRankComputer<T>, GaussianElimination<T>>();
            resolver.EnsureIsRegistered<IDeterminantComputer<T>, LaplaceDeterminantFormula<T>>();
            resolver.EnsureIsRegistered<IAdjugateComputer<T>, LaplaceAdjugateFormula<T>>();
            resolver.EnsureIsRegistered<IInverseComputer<T>, LaplaceInverseFormula<T>>();
        }

        #endregion
    }
}